/*
 *Copyright (c) [2019-2020]  C2comm, Inc.  All rights reserved.
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; If not, see <https://www.gnu.org/licenses/>
 */

/*
 *Vendor: C2comm
 *Version: 1.0
 *Filename: TimeOutControl.v
 *Target Device: Altera
 *Author : 刘晓骏
*/

module TimeOutControl(
    input  wire         SYS2CORE_clk,
    input  wire         SYS2CORE_rst_n,
    input  wire [ 42:0] G_current_state,
    input  wire [336:0] CONF2CORE_cm_static_conf,

    output reg          TOC2SCT_time_out,

    output wire [298:0] CORE2MON_cm_state
);
/*//////////////////////////////////////////////////////////
                    中间变量声明区域
*///////////////////////////////////////////////////////////
//本模块中所有中间变量(wire/reg/parameter)在此集中声明 
reg [ 1:0] cm_listen_param_set;

reg [19:0] curr_local_timer;
reg [19:0] next_local_timer;

localparam CM_INTEGRATE  = 6'b000001,
           CM_UNSYNC     = 6'b000010,
           CM_CA_ENABLED = 6'b000100,
           CM_WAIT_4_IN  = 6'b001000,
           CM_SYNC       = 6'b010000,
           CM_STABLE     = 6'b100000;
//***************************************************
//              状态统计信号
//*************************************************** 
assign CORE2MON_cm_state = {26'b0,curr_local_timer,TOC2SCT_time_out,252'b0};

//***************************************************
//              状态统计信号
//***************************************************
always @* begin
    if(((G_current_state[42:37] == CM_UNSYNC) && (G_current_state[2+26+3] == 1'b1)) || 
       ((G_current_state[42:37] == CM_WAIT_4_IN) && (G_current_state[2+17+1] == 1'b1)) ||
       ((G_current_state[42:37] == CM_WAIT_4_IN) && (G_current_state[2+17+2] == 1'b1)) ||
       ((G_current_state[42:37] == CM_SYNC) && (G_current_state[2+8+1] == 1'b1)) || 
       ((G_current_state[42:37] == CM_SYNC) && (G_current_state[2+8+2] == 1'b1)) ||
       ((G_current_state[42:37] == CM_STABLE) && (G_current_state[2+0+1] == 1'b1)) ||
       ((G_current_state[42:37] == CM_STABLE) && (G_current_state[2+0+3] == 1'b1))
      )begin
        next_local_timer = 20'b0;
    end
    else if(((G_current_state[42:37] == CM_UNSYNC) && (G_current_state[2+26+1] == 1'b1)) || 
            ((G_current_state[42:37] == CM_UNSYNC) && (G_current_state[2+26+2] == 1'b1))
           )begin
     
        next_local_timer = CONF2CORE_cm_static_conf[151:132];
    end
    else if((G_current_state[42:37] == CM_CA_ENABLED) && (G_current_state[2+22+1] == 1'b1)) begin
     
        next_local_timer = CONF2CORE_cm_static_conf[131:112];
    end
    else begin//累减
        next_local_timer = (curr_local_timer == 20'b0) ? curr_local_timer : curr_local_timer - 1'b1;
    end
end



always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(~SYS2CORE_rst_n) begin
		 cm_listen_param_set <= 2'b11;
	 end
	 else begin
		 cm_listen_param_set <= {cm_listen_param_set[0],1'b0};
	 end
end


always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(~SYS2CORE_rst_n) begin
        curr_local_timer <= 20'hFFFFF;
      
    end
    else if(cm_listen_param_set>2'd0) begin
		  curr_local_timer <= CONF2CORE_cm_static_conf[171:152];
	 end
    else begin
        curr_local_timer <= next_local_timer;
    end
end

//超时信号
always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(~SYS2CORE_rst_n) begin
        TOC2SCT_time_out <= 1'b0;
    end
    else begin
        TOC2SCT_time_out <= ((curr_local_timer == 20'b0) || (next_local_timer == 20'b0));
    end
end
/*//////////////////////////////////////////////////////////
                   IP调用区域
*///////////////////////////////////////////////////////////
//本模块调用的所有IP在该区域实例化
//例如fifo/ram/grant之类的IP.... 
endmodule
/*
TimeOutControl TimeOutControl_inst(
    .SYS2CORE_clk(),
    .SYS2CORE_rst_n(),
    .G_current_state(),
    .CONF2CORE_cm_static_conf(),

    .TOC2SCT_time_out(),

    .CORE2MON_cm_state()
);
*/